1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * @addtogroup Looper
19  * @{
20  */
21 
22 /**
23  * @file looper.h
24  */
25 
26 module android.ndk.looper;
27 
28 import arsd.jni;
29 import android.ndk;
30 
31 extern (C):
32 nothrow:
33 @nogc:
34 
35 struct ALooper;
36 /**
37  * ALooper
38  *
39  * A looper is the state tracking an event loop for a thread.
40  * Loopers do not define event structures or other such things; rather
41  * they are a lower-level facility to attach one or more discrete objects
42  * listening for an event.  An "event" here is simply data available on
43  * a file descriptor: each attached object has an associated file descriptor,
44  * and waiting for "events" means (internally) polling on all of these file
45  * descriptors until one or more of them have data available.
46  *
47  * A thread can have only one ALooper associated with it.
48  */
49 
50 /**
51  * Returns the looper associated with the calling thread, or NULL if
52  * there is not one.
53  */
54 ALooper* ALooper_forThread ();
55 
56 /** Option for for ALooper_prepare(). */
57 enum
58 {
59     /**
60      * This looper will accept calls to ALooper_addFd() that do not
61      * have a callback (that is provide NULL for the callback).  In
62      * this case the caller of ALooper_pollOnce() or ALooper_pollAll()
63      * MUST check the return from these functions to discover when
64      * data is available on such fds and process it.
65      */
66     ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1 << 0
67 }
68 
69 /**
70  * Prepares a looper associated with the calling thread, and returns it.
71  * If the thread already has a looper, it is returned.  Otherwise, a new
72  * one is created, associated with the thread, and returned.
73  *
74  * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
75  */
76 ALooper* ALooper_prepare (int opts);
77 
78 /** Result from ALooper_pollOnce() and ALooper_pollAll(). */
79 enum
80 {
81     /**
82      * The poll was awoken using wake() before the timeout expired
83      * and no callbacks were executed and no other file descriptors were ready.
84      */
85     ALOOPER_POLL_WAKE = -1,
86 
87     /**
88      * Result from ALooper_pollOnce() and ALooper_pollAll():
89      * One or more callbacks were executed.
90      */
91     ALOOPER_POLL_CALLBACK = -2,
92 
93     /**
94      * Result from ALooper_pollOnce() and ALooper_pollAll():
95      * The timeout expired.
96      */
97     ALOOPER_POLL_TIMEOUT = -3,
98 
99     /**
100      * Result from ALooper_pollOnce() and ALooper_pollAll():
101      * An error occurred.
102      */
103     ALOOPER_POLL_ERROR = -4
104 }
105 
106 /**
107  * Acquire a reference on the given ALooper object.  This prevents the object
108  * from being deleted until the reference is removed.  This is only needed
109  * to safely hand an ALooper from one thread to another.
110  */
111 void ALooper_acquire (ALooper* looper);
112 
113 /**
114  * Remove a reference that was previously acquired with ALooper_acquire().
115  */
116 void ALooper_release (ALooper* looper);
117 
118 /**
119  * Flags for file descriptor events that a looper can monitor.
120  *
121  * These flag bits can be combined to monitor multiple events at once.
122  */
123 enum
124 {
125     /**
126      * The file descriptor is available for read operations.
127      */
128     ALOOPER_EVENT_INPUT = 1 << 0,
129 
130     /**
131      * The file descriptor is available for write operations.
132      */
133     ALOOPER_EVENT_OUTPUT = 1 << 1,
134 
135     /**
136      * The file descriptor has encountered an error condition.
137      *
138      * The looper always sends notifications about errors; it is not necessary
139      * to specify this event flag in the requested event set.
140      */
141     ALOOPER_EVENT_ERROR = 1 << 2,
142 
143     /**
144      * The file descriptor was hung up.
145      * For example, indicates that the remote end of a pipe or socket was closed.
146      *
147      * The looper always sends notifications about hangups; it is not necessary
148      * to specify this event flag in the requested event set.
149      */
150     ALOOPER_EVENT_HANGUP = 1 << 3,
151 
152     /**
153      * The file descriptor is invalid.
154      * For example, the file descriptor was closed prematurely.
155      *
156      * The looper always sends notifications about invalid file descriptors; it is not necessary
157      * to specify this event flag in the requested event set.
158      */
159     ALOOPER_EVENT_INVALID = 1 << 4
160 }
161 
162 /**
163  * For callback-based event loops, this is the prototype of the function
164  * that is called when a file descriptor event occurs.
165  * It is given the file descriptor it is associated with,
166  * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
167  * and the data pointer that was originally supplied.
168  *
169  * Implementations should return 1 to continue receiving callbacks, or 0
170  * to have this file descriptor and callback unregistered from the looper.
171  */
172 alias ALooper_callbackFunc = int function (int fd, int events, void* data);
173 
174 /**
175  * Waits for events to be available, with optional timeout in milliseconds.
176  * Invokes callbacks for all file descriptors on which an event occurred.
177  *
178  * If the timeout is zero, returns immediately without blocking.
179  * If the timeout is negative, waits indefinitely until an event appears.
180  *
181  * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
182  * the timeout expired and no callbacks were invoked and no other file
183  * descriptors were ready.
184  *
185  * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
186  *
187  * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
188  * timeout expired.
189  *
190  * Returns ALOOPER_POLL_ERROR if an error occurred.
191  *
192  * Returns a value >= 0 containing an identifier (the same identifier
193  * `ident` passed to ALooper_addFd()) if its file descriptor has data
194  * and it has no callback function (requiring the caller here to
195  * handle it).  In this (and only this) case outFd, outEvents and
196  * outData will contain the poll events and data associated with the
197  * fd, otherwise they will be set to NULL.
198  *
199  * This method does not return until it has finished invoking the appropriate callbacks
200  * for all file descriptors that were signalled.
201  */
202 int ALooper_pollOnce (int timeoutMillis, int* outFd, int* outEvents, void** outData);
203 
204 /**
205  * Like ALooper_pollOnce(), but performs all pending callbacks until all
206  * data has been consumed or a file descriptor is available with no callback.
207  * This function will never return ALOOPER_POLL_CALLBACK.
208  */
209 int ALooper_pollAll (int timeoutMillis, int* outFd, int* outEvents, void** outData);
210 
211 /**
212  * Wakes the poll asynchronously.
213  *
214  * This method can be called on any thread.
215  * This method returns immediately.
216  */
217 void ALooper_wake (ALooper* looper);
218 
219 /**
220  * Adds a new file descriptor to be polled by the looper.
221  * If the same file descriptor was previously added, it is replaced.
222  *
223  * "fd" is the file descriptor to be added.
224  * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
225  * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
226  * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
227  * "callback" is the function to call when there is an event on the file descriptor.
228  * "data" is a private data pointer to supply to the callback.
229  *
230  * There are two main uses of this function:
231  *
232  * (1) If "callback" is non-NULL, then this function will be called when there is
233  * data on the file descriptor.  It should execute any events it has pending,
234  * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
235  *
236  * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
237  * when its file descriptor has data available, requiring the caller to take
238  * care of processing it.
239  *
240  * Returns 1 if the file descriptor was added or -1 if an error occurred.
241  *
242  * This method can be called on any thread.
243  * This method may block briefly if it needs to wake the poll.
244  */
245 int ALooper_addFd (
246     ALooper* looper,
247     int fd,
248     int ident,
249     int events,
250     ALooper_callbackFunc callback,
251     void* data);
252 
253 /**
254  * Removes a previously added file descriptor from the looper.
255  *
256  * When this method returns, it is safe to close the file descriptor since the looper
257  * will no longer have a reference to it.  However, it is possible for the callback to
258  * already be running or for it to run one last time if the file descriptor was already
259  * signalled.  Calling code is responsible for ensuring that this case is safely handled.
260  * For example, if the callback takes care of removing itself during its own execution either
261  * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
262  * again at any later time unless registered anew.
263  *
264  * Returns 1 if the file descriptor was removed, 0 if none was previously registered
265  * or -1 if an error occurred.
266  *
267  * This method can be called on any thread.
268  * This method may block briefly if it needs to wake the poll.
269  */
270 int ALooper_removeFd (ALooper* looper, int fd);
271 
272 // ANDROID_LOOPER_H
273 
274 /** @} */